#include "mainwindow.h"
#include "ui_mainwindow.h"
//#include "QThread"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , dirPath("NULL")
{
    ui->setupUi(this);

    server = new QTcpServer(this);

    showLocalIPAddr();
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 显示本地可用的ip地址
void MainWindow::showLocalIPAddr()
{
    // 获取本地ip地址 过滤ipv4协议地址
    QStringList ipList;
    for(QHostAddress addr : QNetworkInterface::allAddresses()){
        if(addr.protocol() == QAbstractSocket::IPv4Protocol){
            ipList.push_back(addr.toString());
        }
    }

    ui->comboBoxIPAddress->addItems(ipList);
}

// 将文件夹中的文件信息封装字符串的函数
QString MainWindow::packageFileInfoData()
{
    QDir dir(dirPath);
    QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files);

    QString tempString = "";
    for(auto item : fileInfoList){
        tempString = tempString + item.fileName() + "," + QString::number(item.size()) + "$";
    }

    return tempString;
}

// 信号与槽的集中配置
void MainWindow::connectSocket()
{
    // 收到客户端发来的信息
    connect(socket, &QTcpSocket::readyRead, this, &MainWindow::dealMsgFromClient);

    // 客户端断开连接
    connect(socket, &QTcpSocket::disconnected, this,
            [this]{
        socket->close();
        socket = nullptr;
    });
}

// 将可下载目录发送给客户端
void MainWindow::downloadItemSendToClient()
{
    // 加装数据标识位
    socket->write(("1" + packageFileInfoData()).toUtf8());
}

// 打开成功，传输文件(关键代码)
void MainWindow::sendFile(QFile &file)
{
    // 先发送标识符表示即将开始传输
    //socket->write("8");
    //socket->flush();
    while (!file.atEnd()) {
        // 假设目标是x kb/s, 数字可以换成 x * 1024;
        socket->write(file.read(1024 * 5));
        qDebug() << "发送中";
        // 可以添加适当的延迟，确保数据发送完成
        //QThread::msleep(50);
        socket->waitForBytesWritten();
    }
    //socket->waitForBytesWritten();
    // 传输结束 传输标识符6，在大型项目中这些数字标识符可以用宏替换
    //socket->write("6");
    ui->textBrowserLog->append("下载完毕!!!");
    file.close();
}

// 处理来自客户端的请求
void MainWindow::dealMsgFromClient()
{
    QString fileName = QString::fromUtf8(socket->readAll());
    ui->textBrowserLog->append("用户请求下载 " + fileName);
    qDebug() << dirPath + "/" + fileName;
    // 创建文件对象
    QFile file(dirPath + "/" + fileName);

    if(!file.open(QIODevice::ReadOnly)){
        // 打开失败说明请求错误
        socket->write("0");
        return ;
    }

    sendFile(file);
}

// 打开服务器服务的按钮点击事件
void MainWindow::on_pushButtonOpenServer_clicked()
{
    // 开启服务器的监听， 端口
    server->listen(QHostAddress(ui->comboBoxIPAddress->currentText()), 6789);
    ui->textBrowserLog->append("服务器启动监听,等待客户端连接");

    // 在客户端连接后配置信号和槽
    connect(server, &QTcpServer::newConnection, this,
            [this]{
        if(socket != nullptr)// 只允许一个客户端连接
            return;

        socket = server->nextPendingConnection();

        ui->pushButtonChooseDir->setEnabled(false);
        ui->pushButtonOpenServer->setEnabled(false);
        ui->textBrowserLog->append("客户端连接成功!!!");

        downloadItemSendToClient();
        connectSocket();
    });
}

// 选择文件夹按钮的点击事件
void MainWindow::on_pushButtonChooseDir_clicked()
{
    QString tempPath = QFileDialog::getExistingDirectory();
    if(tempPath == nullptr){
        QMessageBox::information(this, "注意", "你需要选择一个文件夹才行！");
        return ;
    }

    dirPath = tempPath;
    ui->pushButtonOpenServer->setEnabled(true);
}

